var http=require('http');
var fs=require('fs');
var cluster=require('cluster');
var domain=require('domain');
var express=require('express');
var mongoose=require('mongoose');
var cookieParser=require('cookie-parser');
var session=require('express-session');
var ConnectMongo = require('connect-mongo')(session);
var bodyParser=require('body-parser');
var formidable=require('formidable');
var flash = require('connect-flash');
var config=require('./config/config');
var cats=require('./cats');

var expHbs=require('express-handlebars').create({
    defaultLayout:'main',
    extname:'.hbs',
    helpers:{
        section: function (name, opts) {
            if(!this._sections)this._sections={};
            this._sections[name]=opts.fn(this);
            return null;
        },
        addOne: function (idx) {
            return idx+1;
        },
        topN: function (idx,opts) {
            if(idx<opts.hash.n){
                return opts.fn(this);
            }else{
                return '';
            }
        },
        pageHelper:function(times,opts){
            var str='',curr=times.curr;
            for(var i=times.start;i<=times.end;i++){
                times.idx=i;
                times.isCurr=curr==i?true:false;
                str+=opts.fn(times);
            }
            return str;
        }
    }
});
var server;
var app=express();

//config
app.engine('hbs',expHbs.engine);
app.set('view engine','hbs');
app.set('port',5631);

//全局常量
app.locals.imagesCDN=config.imagesCDN;
app.locals.cats=cats.map((cat,i)=>{
    cat.tabCurr=0==i;
    return cat;
});

//会话变量
/*
app.use((req,res,next)=>{
    res.locals.user=req.session.user;
    res.locals.success=req.flash('success').toString();
    res.locals.error=req.flash('error').toString();
    next();
});
*/


//domain
app.use((req,res,next)=>{
    var d=domain.create();

    //错误处理
    d.on('error',(err)=>{
        console.error('Domain error caught:\n',err.stack);
        try{
            //2秒后故障保护关机
            setTimeout(()=>{
                console.error('Failsafe shutdown.');
                process.exit(1);
            },2000);

            //从集群中断开
            var worker=cluster.woker;
            if(worker)worker.disconnect();

            //停止接收请求
            server.close();

            try{
                //尝试使用Express错误路由
                next(err);
            }catch(e){
                //如果Express错误路由失效，尝试返回普通文本响应
                console.error('Express error mechanism failed:\n',e.stack);
                res.statusCode(500);
                res.setHeader('content-type','text/plain');
                res.end('Server error.');
            }
        }catch(e){
            console.error('Unable to send 500 response.\n',e.stack);
        }
    });

    //向域中添加 请求和响应 对象
    d.add(req);
    d.add(res);

    //执行该域中剩下的请求链
    d.run(next);
});

//common middleware
app.use(flash());
app.use(express.static(__dirname+'/public'));
app.use(cookieParser(config.cookie.secret));
app.use(session({
    store:new ConnectMongo({url:config.mongo.development.connectionString}),
    secret:config.cookie.secret,
    cookie:{maxAge:config.cookie.maxAge}
}));
app.use(bodyParser());
app.use((req,res,next)=>{
    if(cluster.isWorker){
        console.log('Worker %d received request.',cluster.worker.process.pid);
    }
    next();
});


//logger
/*switch(app.get('env')){
    case 'development':
        app.use(require('morgan')('dev'));
        break;
    case 'production':
        app.use(require('express-logger')({
            path:__dirname+'/log/requests.log'
        }));
        break;
}*/

//mongoose
var opts={
    server:{
        socketOptions:{
            keepAlive:1
        }
    }
};
switch(app.get('env')){
    case 'development':
        mongoose.connect(config.mongo.development.connectionString,opts);
        break;
    case 'production':
        mongoose.connect(config.mongo.production.connectionString,opts);
        break;
    default :
        throw new Error('Unknown execution environment:'+app.get('env'));
}

//route
//Home
app.use('/',require('./router/index'));

//图书列表页
app.use('/list',require('./router/list'));

//图书详细页
app.use('/item',require('./router/item'));

//搜索列表
app.use('/search',require('./router/search'));

//test
app.use('/test',require('./router/test'));

//Captcha-验证码
app.use('/captcha',require('./router/captcha'));

//register
app.use('/register',require('./router/register'));

//login
app.use('/login',require('./router/login'));

//logout
app.use('/logout',require('./router/logout'));

//个人中心
app.use('/ucenter',require('./router/ucenter'));

//收藏
//app.use('/ucenter/favorite',require('./router/favorite'));

//404
app.use(function (req, res) {
    res.status(404).render('404',{title:'404-Not Found',layout:false});
});

//500
app.use(function (err,req, res) {
    console.log('Server Error:',err);
    res.status(500).render('500',{title:'500- Server Error',layout:false,err:err});
});

function startServer(){
    server=http.createServer(app).listen(app.get('port'),()=>{
        console.info('------------------------------51TechBook port:%d----%s------------------------------',app.get('port'),new Date().toString());
    });
}

if(require.main===module){
    startServer();
}else{
    module.exports=startServer;
}